package com.bkgy.controller.qualityDaily.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bkgy.controller.qualityDaily.entity.QualitydailyMain;
import com.bkgy.controller.qualityDaily.entity.RepQuaMainData;
import com.bkgy.controller.qualityDaily.entity.pdo.*;
import com.bkgy.controller.qualityDaily.mapper.IQualitydailyMainMapper;
import com.bkgy.controller.qualityDaily.service.IQualitydailyMainDataService;
import com.bkgy.controller.qualityDaily.service.IQualitydailyMainService;
import com.bkgy.sys.common.entity.ResultData;
import com.bkgy.util.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class QualitydailyMainServiceImpl extends ServiceImpl<IQualitydailyMainMapper, QualitydailyMain>
        implements IQualitydailyMainService {
    private final IQualitydailyMainDataService mainDataService;

    @Override
    public ResultData selectPage(MainQueryReq req) {
        Page<QualitydailyMain> p = new Page<>(req.getPageIndex(), req.getPageSize());
        LambdaQueryWrapper<QualitydailyMain> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(req.getDbegin())) {
            String shijian = req.getDbegin();
            wrapper.ge(QualitydailyMain::getYearMonthDay, shijian);
        }
        if (StringUtils.isNotEmpty(req.getDend())) {
            String shijian = req.getDend();
            wrapper.le(QualitydailyMain::getYearMonthDay, shijian);
        }
        if (StringUtils.isNotEmpty(req.getArea())) wrapper.eq(QualitydailyMain::getArea, req.getArea());
        List<QualitydailyMain> dbList = page(p, wrapper).getRecords();
        List<MainSaveReq> list = new ArrayList<>();
        String[] unitArr = new String[]{"酸轧", "酸轧", "连退", "连退", "5#镀锌", "5#镀锌", "保障", "保障", "保障", "其它"};
        String[] belongArr = new String[]{"生产", "设备", "生产", "设备", "生产", "设备", "磨辊", "公辅", "运转", "其它",};
        for (QualitydailyMain qm : dbList) {
            MainSaveReq obj = new MainSaveReq();
            obj.setId(qm.getId());
            obj.setYearMonthDay(qm.getYearMonthDay());
            obj.setArea(qm.getArea());
            obj.setCreateTime(qm.getCreateTime());

            List<MainSaveTable> tableList = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                try {
                    MainSaveTable table = new MainSaveTable();
                    table.setArea(qm.getArea());
                    table.setUnit(unitArr[i]);
                    table.setBelong(belongArr[i]);
                    table.setOne((BigDecimal) qm.getClass().getMethod("getCol" + i + 0).invoke(qm));
                    table.setTwo((BigDecimal) qm.getClass().getMethod("getCol" + i + 1).invoke(qm));
                    table.setThree((BigDecimal) qm.getClass().getMethod("getCol" + i + 2).invoke(qm));
                    tableList.add(table);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            obj.setMainTable(tableList);
            list.add(obj);
        }
        return ResultData.ResultDataSuccess(list, list.size());
    }

    @Override
    public ResultData<String> saveQualitydailyMain(QualitydailyMain qualitydailyMain) {
        boolean res = save(qualitydailyMain);
        return ResultData.ResultDataSuccess(res ? "SUCCESS" : "FAIL");
    }

    @Override
    public ResultData<String> updateQualitydailyMain(QualitydailyMain qualitydailyMain) {
        boolean res = false;
        res = updateById(qualitydailyMain);
        return ResultData.ResultDataSuccess(res ? "SUCCESS" : "FAIL");
    }

    @Override
    public ResultData<String> deleteQualitydailyMain(QualitydailyMain qualitydailyMain) {
        boolean res = false;
        if (qualitydailyMain.getId() != null) {
            res = removeById(qualitydailyMain.getId());
        } else {
            LambdaQueryWrapper<QualitydailyMain> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(QualitydailyMain::getYearMonthDay, qualitydailyMain.getYearMonthDay()).eq(QualitydailyMain::getArea, qualitydailyMain.getArea());
            res = remove(wrapper);
        }
        return ResultData.ResultDataSuccess(res ? "SUCCESS" : "FAIL");
    }

    @Override
    public ResultData<JSONObject> mainLineRep() {
        LambdaQueryWrapper<RepQuaMainData> w = new LambdaQueryWrapper<>();
        w.orderByDesc(RepQuaMainData::getShijian).last(" FETCH FIRST 10 ROWS ONLY");
        List<RepQuaMainData> mainDataList = mainDataService.list(w);
        Collections.reverse(mainDataList);
        List<String> xList = new ArrayList<>();
        List<BigDecimal> yuanpinList = new ArrayList<>();
        List<BigDecimal> feicjList = new ArrayList<>();
        List<BigDecimal> fengbiList = new ArrayList<>();
        for (RepQuaMainData d : mainDataList) {
            String shijian = DateUtil.getDateToString(DateUtil.getStringToDate("yyyyMMdd", d.getShijian()), "MM/dd");
            xList.add(shijian);

            BigDecimal yuanpinRate = BigDecimal.ZERO;
            BigDecimal feicjRate = BigDecimal.ZERO;
            BigDecimal outputWtTotal = d.getOutputWt0().add(d.getOutputWt2()).add(d.getOutputWt4());
            if (outputWtTotal.compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal feicjTotal = d.getFeicijiang0().add(d.getFeicijiang2()).add(d.getFeicijiang4());
                yuanpinRate = BigDecimal.ONE.subtract(feicjTotal.divide(outputWtTotal, 4, BigDecimal.ROUND_HALF_UP));
                feicjRate = feicjTotal.divide(outputWtTotal, 4, BigDecimal.ROUND_HALF_UP);
            }
            yuanpinList.add(yuanpinRate);
            feicjList.add(feicjRate);
            BigDecimal fbTotal = d.getCol01().add(d.getCol11()).add(d.getCol21()).add(d.getCol31())
                    .add(d.getCol41()).add(d.getCol51()).add(d.getCol61()).add(d.getCol71()).add(d.getCol81()).add(d.getCol91());
            fengbiList.add(fbTotal);
        }
        String[] xArr = xList.toArray(new String[xList.size()]);
        JSONObject res = new JSONObject();
        JSONObject yuanpin = new JSONObject();
        yuanpin.put("x", xArr);
        yuanpin.put("y", yuanpinList.toArray(new BigDecimal[yuanpinList.size()]));
        res.put("yuanpin", yuanpin);
        JSONObject feici = new JSONObject();
        feici.put("x", xArr);
        feici.put("y", feicjList.toArray(new BigDecimal[feicjList.size()]));
        res.put("feici", feici);
        JSONObject fengbi = new JSONObject();
        fengbi.put("x", xArr);
        fengbi.put("y", fengbiList.toArray(new BigDecimal[fengbiList.size()]));
        res.put("fengbi", fengbi);
        return ResultData.ResultDataSuccess(res);
    }

    @Override
    public ResultData<List<MainRepRes>> mainRep(QualityReq req) {
        String[] unitArr = new String[]{"酸轧", "酸轧", "连退", "连退", "5#镀锌", "5#镀锌", "保障", "保障", "保障", "其它", "三冷合计"};
        String[] belongArr = new String[]{"生产", "设备", "生产", "设备", "生产", "设备", "磨辊", "公辅", "运转", "", ""};
        List<MainRepRes> repList = new ArrayList<>();
        for (int i = 0; i < unitArr.length; i++) {
            MainRepRes res = new MainRepRes();
            res.setUnit(unitArr[i]);
            res.setBelong(belongArr[i]);
            repList.add(res);
        }

        //不传起始时间，默认查询累计本月的
        String beginTime = StringUtils.isNotEmpty(req.getDbegin()) ? req.getDbegin() : DateUtil.thisMonthFirstDay("yyyyMMdd");
        String endTime = StringUtils.isNotEmpty(req.getDend()) ? req.getDend() : DateUtil.nextMonthFirstDay("yyyyMMdd");

        //查询录入的最新记录目标
        LambdaQueryWrapper<QualitydailyMain> w = new LambdaQueryWrapper<>();
        w.orderByDesc(QualitydailyMain::getId).last(" FETCH FIRST 1 ROWS ONLY");
        QualitydailyMain targetCol = getOne(w);

        RepQuaMainData todayMainData = new RepQuaMainData();//当天记录对象
        RepQuaMainData sumMainData = new RepQuaMainData();//累计记录对象

        //查询基础产量数据
        LambdaQueryWrapper<RepQuaMainData> w2 = new LambdaQueryWrapper<>();
        w2.ge(RepQuaMainData::getShijian, beginTime).le(RepQuaMainData::getShijian, endTime)
                .orderByAsc(RepQuaMainData::getShijian);
        List<RepQuaMainData> mainDataList = mainDataService.list(w2);
        for (RepQuaMainData mainData : mainDataList) {
            //分离出当天记录
            if (mainData.getShijian().equals(DateUtil.getDateToString("yyyyMMdd"))) {
                todayMainData = mainData;
            }
            //将全部数据累加起来
            try {
                //累加总产出和总废次降
                for (int i = 0; i < 5; i += 2) {
                    BigDecimal outputWtSum = (BigDecimal) sumMainData.getClass().getMethod("getOutputWt" + i).invoke(sumMainData);
                    BigDecimal outputWt = (BigDecimal) mainData.getClass().getMethod("getOutputWt" + i).invoke(mainData);
                    sumMainData.getClass().getMethod("setOutputWt" + i, BigDecimal.class).invoke(sumMainData, outputWtSum.add(outputWt));
                    BigDecimal feiciSum = (BigDecimal) sumMainData.getClass().getMethod("getFeicijiang" + i).invoke(sumMainData);
                    BigDecimal feici = (BigDecimal) mainData.getClass().getMethod("getFeicijiang" + i).invoke(mainData);
                    sumMainData.getClass().getMethod("setFeicijiang" + i, BigDecimal.class).invoke(sumMainData, feiciSum.add(feici));
                }
                for (int i = 0; i < 10; i++) {
                    for (int j = 0; j < 2; j++) {
                        BigDecimal oldValue = (BigDecimal) sumMainData.getClass().getMethod("getCol" + i + j).invoke(sumMainData);
                        BigDecimal currentValue = (BigDecimal) mainData.getClass().getMethod("getCol" + i + j).invoke(mainData);
                        sumMainData.getClass().getMethod("setCol" + i + j, BigDecimal.class).invoke(sumMainData, oldValue.add(currentValue));
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        long days = cal.get(Calendar.DAY_OF_MONTH);

        BigDecimal feiCiD = BigDecimal.ZERO;
        BigDecimal feiCiM = BigDecimal.ZERO;
        BigDecimal fengbi0 = BigDecimal.ZERO;
        BigDecimal fengbi1 = BigDecimal.ZERO;
        BigDecimal fengbi2 = BigDecimal.ZERO;
        BigDecimal fengbi3 = BigDecimal.ZERO;
        String[] colArr = new String[]{"setYuanpin0", "setFeici0", "setFengbi0"};
        for (int i = 0; i < 10; i++) {
            try {
                MainRepRes row = repList.get(i);
                for (int j = 0; j < 3; j++) {
                    //赋值目标列
                    BigDecimal v = (BigDecimal) targetCol.getClass().getMethod("getCol" + i + j).invoke(targetCol);
                    row.getClass().getMethod(colArr[j], BigDecimal.class).invoke(row, v);
                }

                BigDecimal outputWtD = BigDecimal.ZERO;//当日产量
                BigDecimal outputWtM = BigDecimal.ZERO;//累加产量
                //生产和设备使用同一的当日、累计重
                if (i == 0 || i == 1) {
                    outputWtD = todayMainData.getOutputWt0();
                    outputWtM = sumMainData.getOutputWt0();
                } else if (i == 2 || i == 3) {
                    outputWtD = todayMainData.getOutputWt2();
                    outputWtM = sumMainData.getOutputWt2();
                } else if (i == 4 || i == 5) {
                    outputWtD = todayMainData.getOutputWt4();
                    outputWtM = sumMainData.getOutputWt4();
                } else {
                    outputWtD = todayMainData.getOutputWt4().add(todayMainData.getOutputWt2()).add(todayMainData.getOutputWt0());
                    outputWtM = sumMainData.getOutputWt4().add(sumMainData.getOutputWt2()).add(sumMainData.getOutputWt0());
                }

                //指标
                if (outputWtD.compareTo(BigDecimal.ZERO) > 0) {
                    //对应的废次重
                    BigDecimal feiciD = (BigDecimal) todayMainData.getClass().getMethod("getCol" + i + 0).invoke(todayMainData);
                    BigDecimal rate1 = outputWtD.subtract(feiciD).divide(outputWtD, 4, BigDecimal.ROUND_HALF_UP);
                    row.setYuanpin1(rate1);
                    row.setYuanpin2(rate1.subtract(row.getYuanpin0()));

                    BigDecimal feiciM = (BigDecimal) sumMainData.getClass().getMethod("getCol" + i + 0).invoke(sumMainData);
                    BigDecimal rate2 = outputWtM.subtract(feiciM).divide(outputWtM, 4, BigDecimal.ROUND_HALF_UP);
                    row.setYuanpin3(rate2);
                    row.setYuanpin4(rate2.subtract(row.getYuanpin0()));

                    //废次
                    BigDecimal rate11 = feiciD.divide(outputWtD, 4, BigDecimal.ROUND_HALF_UP);
                    row.setFeici1(rate11);
                    row.setFeici2(rate11.subtract(row.getFeici0()));
                    row.setFeici3(feiciD);
                    BigDecimal rate22 = feiciM.divide(outputWtM, 4, BigDecimal.ROUND_HALF_UP);
                    row.setFeici4(rate22);
                    row.setFeici5(rate22.subtract(row.getFeici4()));
                    row.setFeici6(feiciM);
                }
                //封闭
                BigDecimal fengbiD = (BigDecimal) todayMainData.getClass().getMethod("getCol" + i + 1).invoke(todayMainData);
                row.setFengbi1(fengbiD);
                row.setFengbi2(fengbiD.multiply(BigDecimal.valueOf(days)));
                BigDecimal fengbiM = (BigDecimal) sumMainData.getClass().getMethod("getCol" + i + 1).invoke(sumMainData);
                row.setFengbi3(fengbiM);

                feiCiD = feiCiD.add(row.getFeici3());
                feiCiM = feiCiM.add(row.getFeici6());
                fengbi0 = fengbi0.add(row.getFengbi0());
                fengbi1 = fengbi1.add(row.getFengbi1());
                fengbi2 = fengbi2.add(row.getFengbi2());
                fengbi3 = fengbi3.add(row.getFengbi3());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        //合计行
        MainRepRes heji = repList.get(10);
        heji.setFeici3(feiCiD);
        heji.setFeici6(feiCiM);
        heji.setFengbi0(fengbi0);
        heji.setFengbi1(fengbi1);
        heji.setFengbi2(fengbi2);
        heji.setFengbi3(fengbi3);

        return ResultData.ResultDataSuccess(repList, repList.size());
    }
}